package context

import (
	"context"
	"encoding/json"
	"github.com/micro/go-micro/v2/metadata"
	"kop/pb"
)

const CtxUserKey = "Json-User"

func NewContext(user pb.User) context.Context {

	var data, _ = json.Marshal(&user)
	var ctx = metadata.NewContext(context.Background(), metadata.Metadata{CtxUserKey: string(data)})
	return ctx
}

// IDs[0]: roleID, IDs[1]: serverID, IDs[2]: guildID, IDs[3]: userID,
func NewUser(IDs ...int32) pb.User {

	var user = pb.User{RoleID: IDs[0]}
	if len(IDs) > 1 {
		user.ServerID = IDs[1]
	}
	if len(IDs) > 2 {
		user.GuildID = IDs[2]
	}
	if len(IDs) > 3 {
		user.UserID = IDs[3]
	}

	return user
}

func GetUser(ctx context.Context) (pb.User, error) {

	var user pb.User
	var str, _ = metadata.Get(ctx, CtxUserKey)

	return user, json.Unmarshal([]byte(str), &user)
}

func WithUser(ctx context.Context, user pb.User) context.Context {

	return context.WithValue(ctx, CtxUserKey, user)
}

type Context struct {
}

// get role ID
func (c *Context) GetRoleID(ctx context.Context) int32 {

	var user, ok = ctx.Value(CtxUserKey).(pb.User)
	if !ok {
		user, _ = GetUser(ctx)
	}

	if user.RoleID == 0 {
		panic("session err")
	} else {
		return user.RoleID
	}
}

// get user ID
func (c *Context) GetUserID(ctx context.Context) int32 {

	var user, ok = ctx.Value(CtxUserKey).(pb.User)
	if !ok {
		user, _ = GetUser(ctx)
	}

	if user.UserID == 0 {
		panic("UserID err")
	} else {
		return user.UserID
	}
}

// get server ID
func (c *Context) GetServerID(ctx context.Context) int32 {

	var user, ok = ctx.Value(CtxUserKey).(pb.User)
	if !ok {
		user, _ = GetUser(ctx)
	}

	if user.ServerID == 0 {
		panic("ServerID err")
	} else {
		return user.ServerID
	}
}

// 公会ID
func (c *Context) GetGuildID(ctx context.Context) int32 {

	var user, ok = ctx.Value(CtxUserKey).(pb.User)
	if !ok {
		user, _ = GetUser(ctx)
	}

	return user.GuildID
}

// IDs[0]: roleID, IDs[1]: serverID, IDs[2]: guildID, IDs[3]: userID,
func TestCtx(IDs ...int32) context.Context {

	var user = NewUser(IDs...)

	return WithUser(NewContext(user), user)
}
